#pragma once

using namespace Gdiplus;

struct tagBullet											//properties of every bullet
{
	double rotatespeed;
	std::wstring picname;
	std::wstring sname;
	int lifespan;
	double v;
	int damage[4];
};

const tagBullet heroBulletNormal = {
	1200,
	L"tankmissile",
	L"Linear",
	100000,
	300,
	{1,2,3,4},
};

const tagBullet heroBulletBomb = {
	1200,
	L"missile",
	L"Linear",
	100000,
	400,
	{2,3,5,8},
};

class Bullet
{
protected:
	double time = 0;
	double vx, vy;																	//velocity vector
	double x, y;																//position
	Image * image;																//image of the bullet
	double angle = 0;
	double rotatespeed;
	//std::wstring picname;
	int width, height;															//bullet is a point, though it has those two properties

	int power = 0;
	int damage[4] = { 0 };
	int livetime = 100000000;
	BulletStrategy * strategy;

public:
	Bullet(const std::wstring & name, int vx, int vy, int x, int y, const std::wstring & sname = L"Linear", int lifespan = 100000, int rotatespeed = 1200);
	Bullet(const tagBullet & bullet, int x, int y, int vx, int vy);
	virtual ~Bullet();

	void update(double dtime);
	void draw(Graphics * graphics);
	virtual void hit() = 0;														//determine what to do when a bullet hit something
	virtual void blast() = 0;													//play the blast animation
	double getX() { return x; }													//get the x pos of the bullet
	double getY() { return y; }													//get the y pos of the bullet
	virtual bool collisiondetect() = 0;											//determine whether the bullet has crashed on something
	int getDamage() { return damage[power]; }
	void setPowerGrade(int grade);
};

class HeroBullet :public Bullet
{
private:

public:
	HeroBullet(const std::wstring & name, int vx, int vy, int x, int y, const std::wstring & sname = L"Linear", int lifespan = 100000, int rotatespeed = 1200);
	HeroBullet(const tagBullet & bullet, int x, int y, int vx, int vy);
	virtual ~HeroBullet();

	bool collisiondetect() override;
};

class EnemyBullet :public Bullet
{
private:

public:
	EnemyBullet(const std::wstring & name, int vx, int vy, int x, int y, const std::wstring & sname = L"Linear", int lifespan = 100000, int rotatespeed = 1200);
	EnemyBullet(const tagBullet & bullet, int x, int y, int vx, int vy);
	virtual ~EnemyBullet();

	bool collisiondetect() override;
};

class DotBullet :public HeroBullet												//a normal bullet emited by hero
{
private:

public:
	DotBullet(const std::wstring & name, int vx, int vy, int x, int y, const std::wstring & sname = L"Linear", int lifespan = 100000, int rotatespeed = 1200);
	DotBullet(const tagBullet & bullet, int x, int y, int vx, int vy);
	~DotBullet();

	void hit() override;
	void blast() override;
};

class Missile :public HeroBullet												//an advanced bullet emited by hero
{
private:

public:
	Missile(const std::wstring & name, int vx, int vy, int x, int y, const std::wstring & sname = L"Linear", int lifespan = 100000, int rotatespeed = 1200);
	Missile(const tagBullet & bullet, int x, int y, int vx, int vy);
	~Missile();

	void hit() override;
	void blast() override;
};

class EDotBullet :public EnemyBullet											//a normal bullet emited by enemy
{
public:
	EDotBullet(const std::wstring & name, int vx, int vy, int x, int y, const std::wstring & sname = L"Linear", int lifespan = 100000, int rotatespeed = 1200);
	EDotBullet(const tagBullet & bullet, int x, int y, int vx, int vy);
	~EDotBullet();

	void hit() override;
	void blast() override;
};